<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 5.6.20                                                   |
// +----------------------------------------------------------------------+
// | Copyright (c) 1999-2016 中企动力                                       |
// +----------------------------------------------------------------------+
// | 微信网页授权                                                            |
// | 网页授权流程分为四步：
// |    1、引导用户进入授权页面同意授权，获取code
// |    2、通过code换取网页授权access_token（与基础支持中的access_token不同）
// |    3、如果需要，开发者可以刷新网页授权access_token，避免过期
// |    4、通过网页授权access_token和openid获取用户基本信息（支持UnionID机制）
// | 实在不明白请参考：https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN                                                            |
// +----------------------------------------------------------------------+
// | Authors: xudong7930 <xudong7930@gmail.com>                           |
// | Date: 2016年5月12日20:43:25                                           |
// +----------------------------------------------------------------------+
//
//
// $Id:$
namespace lib;

class WeixinWebAuth
{
    private $_appid = ""; //微信APPID
    private $_secret = ""; //微信APPSECRET

    //构造函数
    function __construct($appid, $secret)
    {
        $this->_appid = $appid;
        $this->_secret = $secret;
    }

    /**
     * 第一步：用户同意授权，获取code
     *
     * @param string $scope 应用授权作用域 snsapi_base|snsapi_userinfo
     * @param string $url 回调地址
     */
    public function getAuthCode($scope='snsapi_base', $url="")
    {

        $state = time().mt_rand(1000, 9999); //状态,值随便

        $appid = $this->_appid; //APPID

        $rurl = urlencode($url); //回调地址

        $wx_auth_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$rurl&response_type=code&scope=$scope&state=$state#wechat_redirect";

        header('Location: '.$wx_auth_url);
    }


    /**
     * 第二步：通过code换取网页授权access_token
     * @param $code
     * @return mixed
     */
    public function getAccessToken($code)
    {
        $appid = $this->_appid;
        $secret = $this->_secret;

        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token';
        $header = array();
        $data = array(
            'appid'=>$appid,
            'secret'=>$secret,
            'code'=>$code,
            'grant_type'=>'authorization_code');

        $wx_result = self::CURL_HTTPS($url, $data, $header, 30, false);

        return $wx_result;
    }


    /**
     * 第三步：刷新access_token（如果需要）
     * @param $retoken
     * @return mixed
     */
    public function regetAccessToken($retoken)
    {
        $wx_url = "https://api.weixin./qq.com/sns/oauth2/refresh_token";
        $header = array();
        $data = array('refresh_token'=>$retoken);

        $response = self::CURL_HTTPS($wx_url, $data, $header, 30, false);

        return $response;
    }


    /**
     * 第四步：拉取用户信息(需scope为 snsapi_userinfo)
     * @param string $token
     * @param string $openid
     * @param string $lang
     * @return mixed
     */
    public function getWeixinUserinfo($token='', $openid='', $lang='zh_CN') {

        $url = 'https://api.weixin.qq.com/sns/userinfo';

        $header = array();

        $data = array('access_token'=>$token, 'openid'=>$openid, 'lang'=>$lang);

        $response = self::CURL_HTTPS($url, $data, $header, 30, false);

        return $response;
    }


    /**
     * 检验授权凭证（access_token）是否有效
     * @param $openid
     * @param $token
     * @return mixed
     */
    public function checkAccessTokenValid($openid, $token)
    {
        $wx_url = "https://api.weixin.qq.com/sns/auth?access_token";

        $header = array();

        $data = array("access_token"=>$token, 'openid'=>$token);

        $response = self::CURL_HTTPS($wx_url, $data, $header, 30, false);

        return $response;
    }
    

    /**
     * curl 获取 https 请求
     *
     * @param String $url 请求的url
     * @param array $data 要發送的數據
     * @param array $header 请求时发送的header
     * @param int $timeout 超时时间，默认30s
     * @return string
     */
    public static function CURL_HTTPS($url, $data=array(), $header=array(), $timeout=30, $ispost=false){

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, $ispost);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

        $response = curl_exec($ch);

        if($error=curl_error($ch)){
            die($error);
        }

        curl_close($ch);
        return $response;
    }

}